package com.three.config;

import com.three.config.game.annotation.ConfigConstruct;
import com.three.config.game.annotation.ConfigMethodType;
import com.three.utils.ConfigUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Created by mathua on 2017/7/16.
 */
public class ItemConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(ItemConfig.class);
    private static Map<Long, ItemConfig> configs;

    private int id;
    private int itemType;
    private int itemTypeSub;
    private String itemName;//物品名称
    private String itemDescribe;// 物品描述
    private String icon;// 物品图标
    private int lifeTime;// 物品存活时间
    private int accumulateLimit;// 累加上限

    /**
     * 初始化配置表
     *
     * @return
     */
    @ConfigConstruct(type = ConfigMethodType.INIT)
    private static boolean init() {
        configs = ConfigUtils.getConfigs(ItemConfig.class);
        return configs != null;
    }

    /**
     * 检查配置表
     *
     * @return
     */
    @ConfigConstruct(type = ConfigMethodType.CHECK)
    private static boolean check() {
        return configs.values().stream()
                .allMatch(ItemConfig::verfyConfig);
    }

    public static boolean verfyConfig(long id) {
        return configs.containsKey(id);
    }
    public static ItemConfig get(int id) {return configs.get(id);}

    /**
     * TODO 07-09
     * 检查单个配置项
     * @param config
     * @return
     */
    private static boolean verfyConfig(ItemConfig config){
        if(!ItemType.verfy(config.itemType)) {
            LOGGER.error("ItemConfig.ItemType error, configId:{},ItemType:{}", config.id,config.itemType);
            return false;
        }
        if(!ItemTypeSub.verfy(ItemType.get(config.itemType), config.itemTypeSub)) {
            LOGGER.error("ItemConfig.ItemType error, configId:{},ItemType:{},ItemTypeSub:{}", config.id,config.itemType, config.itemTypeSub);
            return false;
        }
        if(config.accumulateLimit < 0) {
            LOGGER.error("ItemConfig.accumulateLimit error, configId:{}, accumulateLimit:{}", config.id,config.accumulateLimit);
            return false;
        }
        if(config.lifeTime < 0) {
            LOGGER.error("ItemConfig.lifeTime error, configId:{}, lifeTime:{}", config.id,config.lifeTime);
            return false;
        }
        return true;
    }

    public int getId() {
        return id;
    }

    public int getItemType() {
        return itemType;
    }

    public int getItemTypeSub() {
        return itemTypeSub;
    }

    public String getItemName() {
        return itemName;
    }

    public String getItemDescribe() {
        return itemDescribe;
    }

    public String getIcon() {
        return icon;
    }

    public int getLifeTime() {
        return lifeTime;
    }

    public int getAccumulateLimit() {
        return accumulateLimit;
    }

    /**
     * 物品类型
     */
    public enum ItemType {
        DAO_JU(1),// 道具
        ;
        private static Map<Integer,ItemType> VALUES= Arrays.stream(ItemConfig.ItemType.values()).collect(Collectors.toMap(t->t.id, Function.identity()));
        ItemType(int id){
            this.id=id;
        }
        public final int id;
        public static boolean verfy(int id){
            return VALUES.containsKey(id);
        }
        public static ItemType get(int id){
            return VALUES.get(id);
        }
    }

    /**
     * 物品子类型
     */
    public enum ItemTypeSub{
        FANG_KA(ItemType.DAO_JU, 1),// 房卡
        ;
        private static Map<ItemType, Map<Integer, ItemTypeSub>> VALUES = new HashMap<>();
        static {
            for(ItemTypeSub typeSub : ItemTypeSub.values()) {
                if(!VALUES.containsKey(typeSub.itemType))
                    VALUES.putIfAbsent(typeSub.itemType, new HashMap<>());
                Map<Integer, ItemTypeSub> SUB_VALUES = VALUES.get(typeSub.itemType);
                SUB_VALUES.putIfAbsent(typeSub.id, typeSub);
            }
        }

        public final int id;
        public final ItemType itemType;
        ItemTypeSub(ItemType itemType, int id) {
            this.itemType = itemType;
            this.id = id;
        }

        public static boolean verfy(ItemType itemType, int id){
            Map<Integer, ItemTypeSub> SUB_VALUES = VALUES.get(itemType);
            return SUB_VALUES != null ? SUB_VALUES.containsKey(id):false;
        }
        public static ItemTypeSub get(ItemType itemType, int id){
            Map<Integer, ItemTypeSub> SUB_VALUES = VALUES.get(itemType);
            return SUB_VALUES != null ? SUB_VALUES.get(id):null;
        }
    }
}
